home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_014 / shell / execom.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  408 lines

  1.  
  2. /*
  3.  * EXECOM.C
  4.  *
  5.  * Matthew Dillon, 24 Feb 1986
  6.  *
  7.  *    This code is particular hacked up and needs re-writing.
  8.  *
  9.  */
  10.  
  11. #include "shell.h"
  12.  
  13.  
  14. struct COMMAND {
  15.    int (*func)();
  16.    int stat;
  17.    int val;
  18.    char *name;
  19. };
  20.  
  21. struct MLIST {
  22.    struct MLIST *next;
  23. };
  24.  
  25. #define F_EXACT   0
  26. #define F_ABBR    1
  27.  
  28. extern char *breakout();
  29.  
  30. extern int do_run(), do_number();
  31. extern int do_quit(), do_set_var(), do_unset_var();
  32. extern int do_echo(), do_source(), do_mv();
  33. extern int do_cd(), do_rm(), do_mkdir(), do_history();
  34. extern int do_mem(), do_cat(), do_dir();
  35. extern int do_foreach();
  36.  
  37. static struct MLIST *Mlist;
  38.  
  39. static struct COMMAND Command[] = {
  40.    do_run      ,  0,          0 ,   "\001",
  41.    do_number   ,  0,          0 ,   "\001",
  42.    do_quit     ,  0,          0 ,   "quit",
  43.    do_set_var  ,  0, LEVEL_SET  ,   "set",
  44.    do_unset_var,  0, LEVEL_SET  ,   "unset",
  45.    do_set_var  ,  0, LEVEL_ALIAS,   "alias",
  46.    do_unset_var,  0, LEVEL_ALIAS,   "unalias",
  47.    do_echo     ,  0,          0 ,   "echo",
  48.    do_source   ,  0,          0 ,   "source",
  49.    do_mv       ,  0,          0 ,   "mv",
  50.    do_cd       ,  0,          0 ,   "cd",
  51.    do_rm       ,  0,          0 ,   "rm",
  52.    do_mkdir    ,  0,          0 ,   "mkdir",
  53.    do_history  ,  0,          0 ,   "history",
  54.    do_mem      ,  0,          0 ,   "mem",
  55.    do_cat      ,  0,          0 ,   "cat",
  56.    do_dir      ,  0,          0 ,   "dir",
  57.    do_dir      ,  0,         -1 ,   "devinfo",
  58.    do_foreach  ,  0,          0 ,   "foreach",
  59.    NULL        ,  0,          0 ,   NULL };
  60.  
  61. static char *
  62. mpush(amount)
  63. {
  64.    struct MLIST *ml;
  65.  
  66.    ml = (struct MLIST *)malloc (amount + sizeof(*Mlist));
  67.    ml->next = Mlist;
  68.    Mlist = ml;
  69.    return ((char *)Mlist + sizeof(*Mlist));
  70. }
  71.  
  72. static char *
  73. mpop()
  74. {
  75.    char *old = NULL;
  76.  
  77.    if (Mlist == NULL) {
  78.       puts ("Internal MLIST error");
  79.       fflush (stdout);
  80.    } else {
  81.       old = (char *)Mlist + sizeof(*Mlist);
  82.       Free (Mlist);
  83.       Mlist = Mlist->next;
  84.    }
  85.    return (old);
  86. }
  87.  
  88. mrm()
  89. {
  90.    while (Mlist) {
  91.       Free (Mlist);
  92.       Mlist = Mlist->next;
  93.    }
  94. }
  95.  
  96. exec_command(base)
  97. char *base;
  98. {
  99.    char *str;
  100.    int i;
  101.    if (!H_stack)
  102.       add_history(base);
  103.    strcpy (str = mpush(strlen(base) + 1), base);
  104.    i = e_command(str);
  105.    if (mpop() != str) {
  106.       puts ("POP ERROR");
  107.       fflush (stdout);
  108.    }
  109.    return (1);
  110. }
  111.  
  112. static
  113. e_command(base)
  114. char *base;
  115. {
  116.    char *com, *start, *avline, *alias;
  117.    char *s1, *s2;
  118.    int flag = 0;
  119.    int i, pcount, len, ccno;
  120. loop:
  121.    com = breakout (&base, &flag);
  122.    if (*com == '\0') {
  123.       if (flag & FL_EOL)
  124.          return (1);
  125.       goto loop;
  126.    }
  127.    alias = NULL;
  128.    if ((ccno = find_command(com, F_EXACT)) < 0) {
  129.       switch (flag & FL_MASK) {
  130.       case FL_BANG:
  131.          alias = get_history (com);
  132.          replace_head (alias, base, flag);
  133.          break;
  134.       case FL_DOLLAR:
  135.          alias = get_var (LEVEL_SET, com + 1);
  136.          break;
  137.       default:
  138.          alias = get_var (LEVEL_ALIAS, com);
  139.          break;
  140.       }
  141.       if (alias == NULL) {
  142.          if ((ccno = find_command (com, F_ABBR)) < 0) {
  143.             printf ("%s Command Not Found\n", com);
  144.             return (-1);
  145.          } else {
  146.             goto good_command;
  147.          }
  148.       }
  149.  
  150.       if (*alias == '%')
  151.          goto good_command;
  152.  
  153.       start = (!(flag & FL_EOC)) ? base : "";
  154.       while (!(flag & FL_EOC)) {
  155.          flag = FL_OVERIDE;
  156.          breakout (&base, &flag);
  157.       }
  158.  
  159.       com = mpush (strlen(alias) + strlen(start) + 2);
  160.       strcpy (com, alias);
  161.       strcat (com, " ");
  162.       strcat (com, start);
  163.       i = e_command (com);
  164.       if (mpop() != com)
  165.          puts ("ME BAE ERROR");
  166.       if (i < 0)
  167.          return (-1);
  168.       if (flag & FL_EOL)
  169.          return (1);
  170.       goto loop;
  171.    }
  172. good_command:
  173.    pcount = 0;
  174.    i = pcount = 0;
  175.    av[i] = mpush (strlen(com) + 1);
  176.    ++pcount;
  177.    strcpy (av[i++], com);
  178.    while (!(flag & FL_EOC)) {
  179.       com = breakout (&base, &flag);
  180.       if (*com == '\0')
  181.          continue;
  182.       switch (flag & FL_MASK) {
  183.       case FL_DOLLAR:
  184.          av[i] = get_var (LEVEL_SET, com + 1);
  185.          if (av[i] == NULL)
  186.             av[i] = com;
  187.          av[i] = strcpy(mpush (strlen(av[i]) + 1), av[i]);
  188.          ++pcount;
  189.          break;
  190.       case FL_QUOTE:
  191.       default:
  192.          av[i] = com;
  193.          break;
  194.       }
  195.       if (flag & FL_IDOLLAR) {
  196.          for (s1 = av[i]; *s1 && *s1 != '$'; ++s1);
  197.          if (*s1) {
  198.             *s1 = '\0';
  199.             s1 = get_var (LEVEL_SET, s1 + 1);
  200.             if (s1) {
  201.                register char *scr_str = mpush(strlen(av[i])+strlen(s1)+1);
  202.                ++pcount;
  203.                strcpy (scr_str, av[i]);
  204.                strcat (scr_str, s1);
  205.                av[i] = scr_str;
  206.             }
  207.          }
  208.       }
  209.       if (flag & FL_WILD) {   /*  av[i] has a wild card, expand it */
  210.          int eac;
  211.          char **eav, **ebase;
  212.  
  213.          eav = ebase = expand (av[i], &eac);   /* returns malloc'd av list */
  214.          if (eav == NULL) {
  215.             puts ("Null expansion");
  216.             goto fail;
  217.          }
  218.          if (i + eac > MAXAV - 2) {
  219.             free_expand (ebase);
  220.             goto avovr;
  221.          }
  222.          for (; eac; --eac, ++eav) {
  223.             av[i++] = strcpy(mpush(strlen(*eav)+1), *eav);
  224.             ++pcount;
  225.          }
  226.          --i;
  227.          free_expand (ebase);
  228.       }
  229.       if (++i > MAXAV - 2) {
  230. avovr:
  231.          puts ("AV overflow");
  232.          goto fail;
  233.       }
  234.    }
  235.    av[i] = NULL;
  236.    ac = i;
  237.    for (len = 0, i = 0; i < ac; ++i)
  238.       len += strlen(av[i]) + 1;
  239.    avline = mpush (len + 1);
  240.    *avline = '\0';
  241.    for (i = 0; i < ac; ++i) {
  242.       strcat (avline, av[i]);
  243.       if (i + 1 < ac)
  244.          strcat (avline, " ");
  245.    }
  246.    if (*alias) {
  247.       for (s2 = alias; *s2 && *s2 != ' '; ++s2);
  248.       if (*s2) {
  249.          *s2 = '\0';
  250.          set_var (LEVEL_SET, alias + 1, next_word(avline));
  251.          *s2 = ' ';
  252.          s1 = strcpy(mpush(strlen(s2)+1), s2);
  253.          i = e_command (s1);
  254.          if (mpop() != s1)
  255.             puts ("AL-LINE ERROR");
  256.       }
  257.    } else {
  258.       i = (*Command[ccno].func)(avline, Command[ccno].val);
  259.    }
  260.    if (mpop() != avline) {
  261.       puts ("AVLINE ERROR");
  262. fail:
  263.       i = -1;
  264.    }
  265.    while (pcount--)
  266.       mpop();
  267.    if (i < 0)
  268.       return (i);
  269.    if (flag & FL_EOL)
  270.       return (1);
  271.    goto loop;
  272. }
  273.  
  274. static char *
  275. breakout(base, flag)
  276. register int *flag;
  277. char **base;
  278. {
  279.    register char *str, *scr;
  280.    register int oflag = *flag;
  281.  
  282. loop:
  283.    *flag = 0;
  284.    str = *base;
  285.    while (*str == ' ' || *str == 9)
  286.       ++str;
  287.    switch (*str) {
  288.    case '\0':
  289.       *flag = FL_EOC | FL_EOL;
  290.       *base = str;
  291.       return (str);
  292.    case '*':
  293.    case '?':
  294.       *flag = FL_WILD;
  295.       break;
  296.    case ';':
  297.       *flag = FL_EOC;
  298.       *str = '\0';
  299.       *base = str + 1;
  300.       return (str);
  301.    case '\"':
  302.       *flag = FL_QUOTE;
  303.       break;
  304.    case '$':
  305.       *flag = FL_DOLLAR;
  306.       break;
  307.    case '%':
  308.       *flag = FL_PERCENT;
  309.       break;
  310.    case '!':
  311.       *flag = FL_BANG;
  312.       break;
  313.    default:
  314.       break;
  315.    }
  316.    scr = str;
  317.    for (;;) {
  318.       switch (*scr) {
  319.       case '$':
  320.          if (scr != str)
  321.             *flag |= FL_IDOLLAR;
  322.          ++scr;
  323.          break;
  324.       case '*':
  325.       case '?':
  326.          *flag |= FL_WILD;
  327.          ++scr;
  328.          break;
  329.       case ' ':
  330.       case 9:
  331.          if (!(oflag & FL_OVERIDE))
  332.             *scr = '\0';
  333.          *base = scr + 1;
  334.          return (str);
  335.       case '\"':                    /* Quote */
  336.          del_char(scr);
  337.          while (*scr && *scr != '\"') {
  338.             if (*scr == '\\') {
  339.                del_char(scr);
  340.                if (*scr)
  341.                   ++scr;
  342.             } else {
  343.                ++scr;
  344.             }
  345.          }
  346.          if (*scr == '\"')
  347.             del_char(scr);
  348.          break;
  349.       case '\0':
  350.          *flag |= FL_EOL | FL_EOC;
  351.          *base = scr;
  352.          return (str);
  353.       case ';':
  354.          *flag |= FL_EOC;
  355.          *base = scr + 1;
  356.          *scr = '\0';
  357.          return (str);
  358.       case '^':
  359.          ++scr;
  360.          if (*scr) {
  361.             *(scr - 1) = *scr & 0x1f;
  362.             del_char (scr);
  363.          }
  364.          break;
  365.       case '\\':
  366.          del_char(scr);
  367.          if (*scr)
  368.             ++scr;
  369.          break;
  370.       default:
  371.          ++scr;
  372.       }
  373.    }
  374. }
  375.  
  376. del_char(str)
  377. register char *str;
  378. {
  379.    for (; *str; ++str)
  380.       str[0] = str[1];
  381. }
  382.  
  383. static
  384. find_command(str, arg)
  385. char *str;
  386. {
  387.    int i;
  388.    int len = strlen(str);
  389.  
  390.    if (*str >= '0'  &&  *str <= '9')
  391.       return (1);
  392.    for (i = 0; Command[i].func; ++i) {
  393.       if (strncmp (str, Command[i].name, len) == 0) {
  394.          if (arg == F_ABBR)
  395.             return (i);
  396.          if (strcmp (str, Command[i].name) == 0)
  397.             return (i);
  398.          return (-1);
  399.       }
  400.    }
  401.    if (arg == F_ABBR)
  402.       return (0);
  403.    return (-1);
  404. }
  405.  
  406.  
  407.  
  408.